package com.health.memberbackstage.filters;

import com.alibaba.fastjson.JSON;
import com.health.memberbackstage.pojo.R.Result;
import com.health.memberbackstage.pojo.R.ResultEnum;
import com.health.memberbackstage.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.MalformedJwtException;
import io.jsonwebtoken.SignatureException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

public class VerifyTokenInterceptor extends BasicAuthenticationFilter {

    public VerifyTokenInterceptor(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        response.setContentType("application/json;charset=utf-8");

        String token = request.getParameter("token");
        if (StringUtils.isEmpty(token)){
            token = request.getHeader("token");
            if (StringUtils.isEmpty(token)){
                chain.doFilter(request,response);
                return;
            }
        }
        try {

            Claims claims = JwtUtils.parseBody(token);
            saveSecurityContext(claims);
            chain.doFilter(request,response);

        }catch (ExpiredJwtException e){
            Claims claims = e.getClaims();

            long ExpireLong = claims.getExpiration().getTime();
            long nowLong = System.currentTimeMillis();

            if (nowLong <= ExpireLong+1000*60*30){
                String newToken = JwtUtils.createToken(claims, claims.getSubject());
                response.setHeader("NEW_TOKEN",newToken);

                saveSecurityContext(claims);
                chain.doFilter(request,response);

            }else {
                Result r = Result.fail(ResultEnum.OVERDUE_TOKEN);
                response.getWriter().write(JSON.toJSONString(r));
            }
        }catch (MalformedJwtException | SignatureException | IllegalArgumentException e){
            Result r = Result.fail(ResultEnum.ILLEGAL_TOKEN);
            response.getWriter().write(JSON.toJSONString(r));
        }
    }

    private void saveSecurityContext(Claims claims){

        String username = claims.get("username", String.class);

        List<GrantedAuthority> authorityList = AuthorityUtils.createAuthorityList();

        Authentication authentication = new UsernamePasswordAuthenticationToken(username,null,authorityList);
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
}